#include "Acceptor.h"
#include "Eventloop.h"

namespace liu
{
	Acceptor::Acceptor(Eventloop* pLoop)
		:m_pLoop(pLoop),
		m_sockfd(::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP)),
		m_acceptChannel(pLoop, m_sockfd)
	{
		cout << debug_time() << "Create acceptor sockfd:[" << m_sockfd << "]." << endl;

		struct sockaddr_in serveraddr;
		bzero(&serveraddr, sizeof serveraddr);
		serveraddr.sin_family = AF_INET;
		serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
		serveraddr.sin_port = htons(SERVER_PORT);
		::bind(m_sockfd, (struct sockaddr*) &serveraddr, sizeof serveraddr);
		m_acceptChannel.SetReadCallback(bind(&Acceptor::handleRead, this));
	}

	Acceptor::~Acceptor()
	{

	}

	void Acceptor::handleRead()
	{
		RUN_TRACE;
		struct sockaddr_in addr;
		bzero(&addr, sizeof addr);

		socklen_t addrlen = static_cast<socklen_t>(sizeof addr);
		int connfd = ::accept4(m_sockfd, (struct sockaddr*)(&addr),
			&addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC);

		cout << debug_time() << "Acceptor::handleRead() get connfd:[" << connfd << "]." << endl;

		if (connfd > 0)
		{
			if (m_newConnCabllback)
			{
				m_newConnCabllback(connfd);
			}
			else
			{
				::close(connfd);
			}
		}
	}

	void Acceptor::listen()
	{
		RUN_TRACE;
		::listen(m_sockfd, SOMAXCONN);
		m_acceptChannel.m_events = EPOLLIN | EPOLLPRI;
		m_acceptChannel.update();
	}


}

